<template>
  <el-form ref="formRef" inline :model="localQueryForm">
    <el-form-item v-for="param in searchParams" :key="param.prop" :prop="param.prop">
      <component
        :is="getComponent(param.component)"
        v-model="localQueryForm[param.prop]"
        clearable
        :multiple="param.multiple"
        :options="param.options"
        :placeholder="param.placeholder"
        :type="param.component === 'textarea' ? 'textarea' : undefined"
        @clear="handleClear(param.prop)"
      />
    </el-form-item>

    <el-form-item>
      <el-button :icon="Search" :loading="listLoading" native-type="submit" type="primary" @click="submitQuery">查询</el-button>
      <el-button :icon="Refresh" @click="resetQuery">重置</el-button>
    </el-form-item>
  </el-form>
</template>

<script lang="ts" setup>
import { Refresh, Search } from '@element-plus/icons-vue'
import { defineEmits, defineProps, ref, watch } from 'vue'
import { type ComponentType, getComponent as getComponentFromMap } from '../componentMap'

const props = defineProps<{
  searchParams: Array<{
    prop: string
    label: string
    component: ComponentType
    options?: Array<{ label: string; value: any }>
    multiple?: boolean
    default?: any
    placeholder?: string
    searchable?: boolean
  }>
  queryForm: any
  listLoading: boolean
}>()

const emit = defineEmits<{
  (e: 'update:queryForm', value: any): void
  (e: 'submit'): void
  (e: 'reset'): void
}>()

const localQueryForm = ref<any>({ ...props.queryForm })

watch(
  () => props.queryForm,
  (newQueryForm) => {
    localQueryForm.value = { ...newQueryForm }
  },
  { immediate: true }
)

const formRef = ref<any>(null)

// 获取组件
const getComponent = (type: ComponentType) => {
  return getComponentFromMap(type)
}

// 提交查询
const submitQuery = () => {
  formRef.value.validate((valid: boolean) => {
    if (valid) {
      emit('update:queryForm', localQueryForm.value)
      emit('submit')
    } else {
      console.log('表单验证失败')
      return false
    }
  })
}

// 重置查询
const resetQuery = () => {
  formRef.value.resetFields()
  const defaultValues = props.searchParams.reduce((acc, param) => {
    acc[param.prop] = param.default ?? null
    return acc
  }, {} as any)
  localQueryForm.value = { ...defaultValues }
  emit('update:queryForm', localQueryForm.value)
  emit('reset')
}

// 清除单个字段
const handleClear = (prop: string) => {
  localQueryForm.value[prop] = null
  emit('update:queryForm', localQueryForm.value)
  emit('submit')
}
</script>

<style scoped>
.el-form-item {
  margin-bottom: 10px;
  margin-right: 16px;
}

:deep(.el-input),
:deep(.el-select) {
  width: 200px;
}

:deep(.el-form-item__content) {
  margin-left: 0 !important;
}
</style>
